#include <queue>

#include "agentModCombineTrees.h"

void agentModCombineTrees::run()
{
    assert(thePool->getCount() > 1);
    solution* parent1 = thePool->getRandomSolution();
    solution* parent2;
    do
    {
        parent2 = thePool->getRandomSolution();
    } while (parent1 == parent2);

    solution* child = new solution(parent1);

    // Choose a random node 
    vector<node *> theNodes;
    
    queue<node *> nodeQ;
    nodeQ.push(child->getRoot());
    while (!nodeQ.empty())
    {
        node* tmp = nodeQ.front();
        nodeQ.pop();
        theNodes.push_back(tmp);

        if (tmp->getLeft() != NULL) nodeQ.push(tmp->getLeft());
        if (tmp->getRight() != NULL) nodeQ.push(tmp->getRight());
    }   

    // Choose another random node 
    vector<node *> theNodes2;
    
    nodeQ.push(parent2->getRoot());
    while (!nodeQ.empty())
    {
        node* tmp = nodeQ.front();
        nodeQ.pop();
        theNodes2.push_back(tmp);

        if (tmp->getLeft() != NULL) nodeQ.push(tmp->getLeft());
        if (tmp->getRight() != NULL) nodeQ.push(tmp->getRight());
    }    


    int ndx = rand() % theNodes.size();
    int ndx2 = rand() % theNodes2.size();
   
    if (rand() % 2 == 0)
    {
        if (theNodes[ndx]->getLeft() != NULL)
            delete theNodes[ndx]->getLeft();
        theNodes[ndx]->setLeft(copySubtree(theNodes2[ndx2]));
    }
    else
    {
        if (theNodes[ndx]->getRight() != NULL)
            delete theNodes[ndx]->getRight();
        theNodes[ndx]->setRight(copySubtree(theNodes2[ndx2]));

    }

    insert(child, parent1, parent2);
}
